#ifndef _GLESLIB_H_
#define _GLESLIB_H_ 

#include <math.h>
#include "../../Define/Defines.h"
#include "stdio.h"

#if !defined(GLESVER)
#define GLESVER GLESVER_1
#endif
#if USEGLESVER_1
#ifdef MAC_OS
	#include <OpenGLES/ES1/gl.h>
#elif defined(QT_CREATOR) || defined(ANDROID_OS)
	#include <GLES/gl.h>
#else
	#include <windows.h>
	#include <gl/gl.h>
	#include "./win/glext.h"
#endif
#elif USEGLESVER_2
#include "../Math/mat4.h"
#ifdef MAC_OS

#elif defined(QT_CREATOR)
#include <QtOpenGL>
#else//windows
#endif
#endif


#define VTX_COUNT_PER_QUAD			4
#define VTX_COUNT_PER_TRI			3
#define VTX_COUNT_PER_LINE			2
#define VTX_COUNT_PER_TRIANGLE		3
#define TRI_COUNT_PER_QUAD			2
#define VTX_COUNT_PER_CIRCLE		19
#define VTX_SIZE					2
#define COLOR_SIZE					4
#define TEXCOOR_SIZE				2
#define MODEL_SIZE					1
#define MODEL_COUNT_PER_QUAD		6
#define NUM_ROTATE_PARAMS			3
#define NUM_SCALE_PARAMS			4
#define NUM_TRANSLATE_PARAMS		2

#define TRANSP_FLAG					(1<<0)
#define SETCLIP_FLAG				(1<<1)
#define CLEARCLIP_FLAG				(1<<2)
#define DRAWLINE_FLAG				(1<<3)
#define ROTATE_FLAG					(1<<4)
#define SCALE_FLAG					(1<<6)
#define DRAWCIRCLE_FLAG				(1<<7)
#define TRANSLATE_FLAG				(1<<8)
#define DRAWTRIANGLE_FLAG			(1<<9)
#define FREE_TRANSFORM_FLAG			(1<<5)
//define for clean code
#if defined(USE_FLOAT_VERTEX_POINTER)
#define GUNIT	float
#define VXTUNIT float
#else
#define GUNIT	int
#define VXTUNIT	UINT16
#endif


#if defined(MAC_OS)||defined(ANDROID_OS)
#define GLORTHO(left,right,bottom,top,near,far)	::glOrthof(left,right,bottom,top,near,far)
#else
#define GLORTHO(left,right,bottom,top,near,far)	::glOrtho(left,right,bottom,top,near,far)
#endif
class GLESLib
{
private:
	UINT32		_nColor2D;
	int			_nNum2DQuads;

	VXTUNIT*		_pVtxBuffer2D;

	UINT8*		_pClrBuffer2D;
	float*		_pTexBuffer2D;
	UINT32*		_pTexID;
	UINT16*		_pIndices;
	UINT16*		_pFlags;
	
#ifdef USE_FREE_TRANSFORM
	float*		_pModBuffer2D;
#endif
	
#ifdef USE_GL_ROTATE
	float*		_pRotateParams;
	bool		_is_rotate;
	float		_rotate_angle;
	float		_rotate_x;
	float		_rotate_y;
#endif
#ifdef USE_TRANSLATE
	float * _pTranslateParams;
	bool	_is_translate;
	float	_translate_x;
	float	_translate_y;
#endif
#ifdef USE_GL_SCALE
	float*		_pScaleParams;
	bool		_is_scale;
	float		_scale_x;
	float		_scale_y;
	float		_scale_center_x;
	float		_scale_center_y;
#endif

#ifdef ENABLE_OPACITY_SETTING
	int			_opacity_percent;
#endif
	
#ifdef USE_DRAW_LINE
	UINT16*		_pLineIndices;
#endif
#ifdef USE_DRAW_CIRCLE
	UINT16*		_pCircleIndices;
#endif //USE_DRAW_CIRCLE
#ifdef USE_DRAW_TRIANGLE
	UINT16*		_pTriangleIndices;
#endif
public:
	//int 		_device_orientation;
	bool _complex_mode;
	int _viewport_orientation;
	int _device_width;
	int _device_height;
	float _viewport_scalew;
	float _viewport_scaleh;	
public:
#if USEGLESVER_2
    GLuint  _glprograme;
    GLuint  _positionLoc;
    GLuint  _texCoordLoc;
    GLuint _colorLoc;
    GLuint _istexLoc;
    // Sampler location
    GLuint _samplerLoc;
    GLuint _modelViewMatrixLoc;
    GLuint LoadShader(const char *shaderSrc, GLenum type);

    CMat4 _modelviewMatrix;
    CMat4 _projectionMatrix;
    CMat4 _modelorginalMatrix;
#endif
#ifdef USE_GL_MULTI_BUFFER
    GLuint _frame_name[GL_NUM_OF_BUFFER];
    GLuint _frame_texture[GL_NUM_OF_BUFFER];
    GLuint _buffer_name[GL_NUM_OF_BUFFER];
    UINT8* _pframe;
    GLuint _curr_frame;
    void bindFrame(int frame_id);
    void unbindFrame();

    GLuint  _glprograme2;
    GLuint _projectionModelMatrixLoc;
    GLuint  _positionLoc2;
    GLuint  _texCoordLoc2;
    GLuint _samplerLoc2;

    CMat4 _projectionModelMatrix;
#endif
	GLESLib(bool complex_mode, int viewport_orientation, int device_width, int device_height);
	~GLESLib();
	void		SetClip(int x, int y, int w, int h);
	void		ClearClip();
	void		SetColor(UINT32 clr) { _nColor2D = clr; }
	void		SetViewPort(int width, int height);
#ifdef USE_DRAW_LINE
	void		DrawLine(GUNIT x1, GUNIT y1, GUNIT x2, GUNIT y2,  bool enableAlpha = false);
	void		DrawLine(GUNIT x1, GUNIT y1, GUNIT x2, GUNIT y2,  int color1, int color2);
	void		DrawRect(GUNIT x, GUNIT y, GUNIT w, GUNIT h,  bool enableAlpha = false); // ricky.nguyen add
#endif
    void FillRect(GUNIT x, GUNIT y, GUNIT w, GUNIT h, bool enableAlpha = false);
#ifdef USE_DRAW_CIRCLE
	void		FillCircle(GUNIT x, GUNIT y, int radius, bool enableAlpha = false);
	void		DrawCircle(GUNIT x, GUNIT y, int radius, bool enableAlpha = false);
#endif //USE_DRAW_CIRCLE

	void		Draw2DTexture(GUNIT x, GUNIT y, int w, int h, GLuint texId, float uv[], int flags, bool enableAlpha);

	void        ShutdownGL();
#ifdef USE_FREE_TRANSFORM
	void		LoadModel(float ox, float oy, float m11, float m12, float m21, float m22);
#endif
	void		CleanCurrentFlag();

	void		ConfigOpenGL();
	void		Flush2D();
	void		Init();
	void		ClearQuads();
	
#ifdef USE_GL_ROTATE
	void		SetRotate(float angle, float x, float y);
	void		ClearRotate();
#endif
#ifdef USE_TRANSLATE
	void SetTranslate(float x, float y);
	void ClearTranslate();
#endif
#ifdef USE_GL_SCALE
	void		SetScale(float scale_x, float scale_y, float center_x, float center_y);
	void		ClearScale();
#endif

#ifdef ENABLE_OPACITY_SETTING
	void		SetOpacity(int percent);
#endif

#ifdef USE_DRAW_TRIANGLE
	void		DrawTriangle(GUNIT x1, GUNIT y1, GUNIT x2, GUNIT y2, GUNIT x3, GUNIT y3, bool enableAlpha = false);
#endif
private:
	void		Clip(int x, int y, int w, int h);

private:
	int _scr_width;
	int _scr_height;
};

#endif